home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
bix02.arc
/
TRAPIT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-08-04
|
6KB
|
181 lines
{stay-resident program with keyboard intercept}
program TrapIt;
{ Program installs itself and traps the [ALT] + [ESC] key. }
{ Compile under Turbo Pascal version 3.00 or higher with }
{ minimun and maximum stack and heap size of about $200. }
{ Run only as a com file. }
const
hot_key = $01; { Escape key }
keyboard_interrupt = $09;
keyboard_data_port = $60;
keyboard_control_port = $61;
clear_keyboard_bit = $80;
interrupt_control_port = $20;
end_of_interrupt_command = $20;
alt_shift_flag_bit = $08;
type
pointer = ^byte;
address = record
offset, segment : integer;
end; {record}
register_pack = record case integer of
1 : (ax, bx, cx, dx, bp, si, di, ds, es, flags : integer);
2 : (al, ah, bl, bh, cl, ch, dl, dh : byte);
end; {record}
var
bios_keyboard_flags : byte absolute $0040:$0017;
registers : register_pack;
kb_data, kb_control : byte;
const
original_vector : address = (offset:0; segment:0);
our_ds : integer = 0;
our_ss : integer = 0;
our_sp : integer = 0;
save_ss : integer = 0;
save_sp : integer = 0;
function stack_pointer: integer;
{ Returns the contents of sp at time of call. }
begin
{ Stack now looks like: [x,bp,ip,fr]. }
inline ($89/$E8/ { mov ax,bp }
$05/$06/$00/ { add ax,6 }
$89/$46/$04); { mov [bp+4],ax }
end; {stack_pointer}
procedure get_vector (interupt : integer; var v);
var
vector : ^byte absolute v;
regs : register_pack;
begin
regs.ah := $35;
regs.al := interupt;
msdos (regs);
vector := ptr(regs.es, regs.bx);
end; {get_vector}
procedure set_vector (interupt : integer; vector : pointer);
var
regs : register_pack;
begin
with regs do begin
ah := $25;
al := interupt;
ds := seg(vector^);
dx := ofs(vector^);
end; {with}
msdos (regs);
end; {set_vector}
procedure terminate_resident;
var
regs : register_pack;
begin
with regs do begin
ah := $31;
al := 0;
dx := memw [cseg - 1 : $0003];
end; {with}
msdos (regs);
end; {terminate_resident}
function alt_key_pressed: boolean;
begin
alt_key_pressed := (bios_keyboard_flags and alt_shift_flag_bit) <> 0;
end; {alt_key_pressed}
procedure do_our_thing;
begin
write ('Gotcha');
end;
procedure interrupt_service_routine;
begin
inline ( $5D/ { pop bp }
$5D/ { pop bp }
$50/ { push ax }
$53/ { push bx }
$51/ { push cx }
$52/ { push dx }
$56/ { push si }
$57/ { push di }
$55/ { push bp }
$06/ { push es }
$1E/ { push ds }
$2E/$8E/$1E/Our_DS/ { mov ds,cs:Our_DS }
$2E/$8C/$16/Save_SS/ { mov cs:Save_SS,ss }
$2E/$89/$26/Save_SP/ { mov cs:Save_SP,sp }
$2E/$8E/$16/Our_SS/ { mov ss,cs:Our_SS }
$2E/$8B/$26/Our_SP { mov sp,cs:Our_sp }
);
if (port [keyboard_data_port] = hot_key) and alt_key_pressed then begin
do_our_thing;
{ Reset keyboard. }
Kb_control := port [Keyboard_control_port];
port [Keyboard_control_port] := Kb_control or Clear_keyboard_bit;
port [Keyboard_control_port] := Kb_control;
port [Interrupt_control_port] := End_of_interrupt_command;
{ Return from interrupt. }
inline ( $2E/$8E/$16/save_ss/ { mov ss,cs:Save_SS }
$2E/$8B/$26/save_sp/ { mov sp,cs:Save_SP }
$1F/ { pop ds }
$07/ { pop es }
$5D/ { pop bp }
$5F/ { pop di }
$5E/ { pop si }
$5A/ { pop dx }
$59/ { pop cx }
$5B/ { pop bx }
$58/ { pop ax }
$CF { iret }
);
end else
{ Pass interrupt on to original handler. }
inline ( $2E/$8E/$16/save_ss/ { mov ss,cs:Save_SS }
$2E/$8B/$26/save_sp/ { mov sp,cs:Save_SP }
$1F/ { pop ds }
$07/ { pop es }
$5D/ { pop bp }
$5F/ { pop di }
$5E/ { pop si }
$5A/ { pop dx }
$59/ { pop cx }
$5B/ { pop bx }
$58/ { pop ax }
$2E/$FF/$2E/original_vector { jmp far Original_V }
);
end; {interrupt_service_routine}
begin
our_ds := dseg;
our_ss := sseg;
our_sp := stack_pointer;
get_vector (keyboard_interrupt, original_vector);
set_vector (keyboard_interrupt, ptr(cseg, ofs(interrupt_service_routine)));
terminate_resident;
end.